var entityCollection = require('../../../Base/server/controllers/EntityCollection'),
    _ = require('lodash'),
    Q = require('q'),
    Transaction = require('../../../Base/server/controllers/Transaction'),
    PublicEnum = require('../../../Base/server/controllers/Enum'),
    mongoose = require('mongoose');
//更新流水信息
exports.updateBizRecordByValue = function (bizRecordId, value, completeFun) {
    var entity = entityCollection.getEntity("BizRecord");
    entity.updateByValue({_id: bizRecordId}, value, function (err, result) {
        completeFun(err, result);
    });
};

//查找条码的所有流水(按时间降序)
exports.findAllByBarcodeMasterAndWork = function (barcodMasterId, workId, completeFun) {
    var entity = entityCollection.getEntity("BizRecord");
    entity.find({
        BarcodeMaster: barcodMasterId,
        Work: workId
    }, {CollectDateTime: -1}, null, function (err, record) {
        if (err) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询条码流水错误';
            newErr.message = '请检查查询参数！';
            completeFun(newErr);
        } else {
            completeFun(null, record);
        }
    });
};
//查找条码流水
exports.findByBarcodeMasterAndWork = function (barcodMasterId, workId, completeFun) {
    var entity = entityCollection.getEntity("BizRecord");
    entity.findOne({
        BarcodeMaster: barcodMasterId,
        Work: workId
    }, [{path: 'Users'}, {path: 'QCUser'}], function (err, record) {
        if (err) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询错误';
            newErr.message = '语法错误，请检查查询参数！';
            completeFun(newErr);
        } else {
            completeFun(null, record);
        }
    });
};
//按条件查询流水
exports.findByCondition = function (condition,completeFun) {
    var entity = entityCollection.getEntity("BizRecord");
    entity.findOne(condition, null, function (err, record) {
        if (err) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询错误';
            newErr.message = '语法错误，请检查查询参数！';
            completeFun(newErr);
        } else {
            completeFun(null, record);
        }
    });

};
//创建条码流水
exports.insert = function (bizRecordData, completeFun) {
    var bizRecordEntity = entityCollection.getEntity("BizRecord");
    bizRecordEntity.insert(bizRecordData, function (err, newBizRecord) {
        completeFun(err, newBizRecord);
    });
};
//创建多条条码流水
exports.addBizRecords = function (bizRecords, completeFun) {


    bizRecords.forEach(function (bizRecord) {
        bizRecord.RowStatus = PublicEnum.RowStatus.Insert;
        bizRecord.CreatedBy = bizRecord.QCUser;
    });

    writeBizRecords(bizRecords).then(function (result) {
        completeFun(null, result);
    }, function (err) {
        var newErr = new Error();
        newErr.leval = 9;
        newErr.title = '创建流水记录失败';
        newErr.message = '';
        completeFun(newErr);

    });

};
function writeBizRecords(bizRecords) {
    var deferred = Q.defer();

    Transaction.BatchSaveByTran([
            {EntityName: 'BizRecord', Records: bizRecords}
        ],
        function (err, result) {
            if (err) {
                deferred.reject(err);
                return;
            }
            deferred.resolve(result);
        }
    );

    return deferred.promise;
}

//删除条码流水
exports.deleteById = function (bizRecordId, completeFun) {
    var bizRecordEntity = entityCollection.getEntity("BizRecord");
    bizRecordEntity.deleteById(bizRecordId, function (err, result) {
        completeFun(err, result);
    });
};

// 查找单品所有流水
exports.findByBarcodeMaster = function (barcodeMasterIds, completeFun) {
    var entity = entityCollection.getEntity("BizRecord");
    entity.find({BarcodeMaster: {$in: barcodeMasterIds}}, {CollectDateTime: 1}, [{
        path: 'Users',
        select: 'Code Name'
    }, {
        path: 'Operation'
    }, {
        path: 'WorkLocation',
        select: 'Code Name Department',
        populate: {
            path: 'Department',
            select: 'Code Name',
            model: 'Department'
        }
    }], function (err, records) {
        if (err) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询错误';
            newErr.message = '语法错误，请检查查询参数！';
            completeFun(newErr);
        } else {
            completeFun(null, records);
        }
    });
};

// 仅供压力测试使用：更新一条条码流水记录
exports.updateOneST = function (barcodMasterId, completeFun) {
    var entity = entityCollection.getEntity("BizRecord");
    entity.findOne({BarcodeMaster: barcodMasterId}, null, function (err, record) {
        if (err || !record) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询错误';
            newErr.message = '语法错误，请检查查询参数！';
            completeFun(newErr);
            return;
        }
        record.BusinessStatus = 1;
        entity.update(record, function (err, modifyRecord) {
            if (err) {
                var newErr = new Error();
                newErr.leval = 9;
                newErr.title = '查询错误';
                newErr.message = '语法错误，请检查查询参数！';
                completeFun(newErr);
                return;
            }
            completeFun(null, modifyRecord);
        });
    });
};

// 根据工位查询最近一条流水档记录
exports.findNearestRecord = function (workLocationId) {
    var deferred = Q.defer();

    var entity = entityCollection.getEntity("BizRecord");
    entity.Entity
        .find({WorkLocation: workLocationId})
        .sort({CollectDateTime: -1})
        .limit(1)
        .exec(function (err, records) {
            if (err) {
                var newErr = new Error();
                newErr.leval = 9;
                newErr.title = '查询错误';
                newErr.message = '语法错误，请检查查询参数！';
                deferred.reject(newErr);
                return;
            }
            deferred.resolve(records);
        });

    return deferred.promise;
}

//首页-质量预警
exports.qualityWaring = function (completeFun) {
    mapReduceByDate().then(function (results) {
        completeFun(null, results);
    }, function (err) {
        completeFun(err);
    });
};

//按时间分组查找流水档
function mapReduceByDate() {
    var deferred = Q.defer();
    var entity = entityCollection.getEntity("BizRecord");
    var barcodeMap = function () {
        var date = this.CollectDateTime;
        var year = date.getFullYear();
        var month = date.getMonth();
        var day = date.getDate();
        var key = year + "-" + (month + 1) + "-" + day;
        emit(key, {bizRecords: [this]});
    };
    var barcodeReduce = function (key, values) {
        var res = {
            bizRecords: []
        };
        values.forEach(function (val) {
            val.bizRecords.forEach(function (obj) {
                res.bizRecords.push(obj);
            });
        });
        return res;
    };

    var barcodeQuery = {
        QCStatus: 1
    };

    var option = {
        map: barcodeMap,
        reduce: barcodeReduce,
        sort: {CollectDateTime: 1},
        query: barcodeQuery
    };
    entity.mapReduce(option, function (err, results) {
        if (err) {
            deferred.reject(err);
        } else {
            var localArray = [],
                batches = [];
            _.forEach(results, function (result) {
                batches.push(diyPopulateBarcodeMaster(result, localArray));
            });
            Q.all(batches).then(function () {
                deferred.resolve(localArray);
            }, function () {
                deferred.reject();
            });
        }
    });

    return deferred.promise;
}

function diyPopulateBarcodeMaster(result, localArray) {
    var deferred = Q.defer();
    var barcodeModel = mongoose.model('BarcodeMaster');
    barcodeModel.populate(result.value.bizRecords, {path: 'BarcodeMaster'}, function (err, resultsBarcodes) {
        if (err) {
            deferred.reject(err);
        } else {
            diyPopulateUser(resultsBarcodes).then(function (record) {
                localArray.push({key: result._id, data: record});
                deferred.resolve(localArray);
            }, function () {
                deferred.reject();
            });
        }
    });

    return deferred.promise;
}

function diyPopulateUser(resultsBarcodes) {
    var deferred = Q.defer();
    var userModel = mongoose.model('User');
    userModel.populate(resultsBarcodes, {path: 'Users'}, function (err, userResult) {
        if (err) {
            deferred.reject(err);
        } else {
            diyPopulateWorkLocation(userResult).then(function (workLocation) {
                deferred.resolve(workLocation);
            }, function () {
                deferred.reject();
            });
        }
    });

    return deferred.promise;
}

function diyPopulateWorkLocation(userResult) {
    var deferred = Q.defer();
    var workLocationModel = mongoose.model('WorkLocation');
    workLocationModel.populate(userResult, {
        path: 'WorkLocation',
        populate: [{
            path: 'Department', select: 'Code Name', model: 'Department'
        }]
    }, function (err, workLocation) {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve(workLocation);
        }
    });
    return deferred.promise;

}

// //根据工位和日期查找流水
// exports.queryByDateAndWorkLocation = function (date, workLocation, completeFun) {
    
//     var entity = entityCollection.getEntity("BizRecord");
//     entity.find({WorkLocation:workLocation, 

//         CollectDateTime:{$gte:date+" 00:00:00",$lte:date+" 23:59:59"}},
//         {CollectDateTime: -1}
//         , [{
//         path: "BarcodeMaster",
//         select: "ItemMasterCode"
//     }], function (err, records) {
//         if (err) {
//             var newErr = new Error();
//             newErr.leval = 9;
//             newErr.title = '查询错误';
//             newErr.message = '查询流水表失败！';
//             completeFun(newErr);
//         } else {
//             completeFun(null, records);
//         }
//     });
// };

//根据工位和日期查找流水
exports.queryByDateAndWorkLocation = function (date, workLocation, completeFun) {
    mapReduceByBarcodeMaster(date, workLocation).then(function (results) {
        completeFun(null, results);
    }, function (err) {
        completeFun(err);
    });
};

//按条码主档分组查找流水档
function mapReduceByBarcodeMaster(date, workLocation) {
    var deferred = Q.defer();
    var entity = entityCollection.getEntity("BizRecord");
    var barcodeMap = function () {
        emit(this.BarcodeMaster, {bizRecords: [this]});
    };
    
    var barcodeReduce = function (key, values) {
        var res = {
            bizRecords: []
        };
        values.forEach(function (val) {
            val.bizRecords.forEach(function (obj) {
                res.bizRecords.push(obj);
            });
        });
        return res;
    };

    var barcodeQuery = {WorkLocation:workLocation, 
        CollectDateTime:{$gte:date+" 00:00:00",$lte:date+" 23:59:59"}};

    var option = {
        map: barcodeMap,
        reduce: barcodeReduce,
        sort: {CollectDateTime: 1},
        query: barcodeQuery
    };
    entity.mapReduce(option, function (err, results) {
        if (err) {
            deferred.reject(err);
        } else {
            var localArray = [],
                batches = [];
            _.forEach(results, function (result) {
                batches.push(getPopulateBarcodeMaster(result, localArray));
            });
            Q.all(batches).then(function () {
                deferred.resolve(localArray);
            }, function () {
                deferred.reject();
            });  
        }
    });


    return deferred.promise;
}
//查询条码主档的关联表
function getPopulateBarcodeMaster(result, localArray) {
    var deferred = Q.defer();
    var barcodeModel = mongoose.model('BarcodeMaster');
    barcodeModel.populate(result.value.bizRecords, {path: 'BarcodeMaster', select: "ItemMasterCode"}, function (err, resultBarcodeMaster) {
        if (err) {
            deferred.reject(err);
        } else {
            //取初次时间的流水
            if(resultBarcodeMaster[0]&&resultBarcodeMaster[0].BarcodeMaster){
                localArray.push(resultBarcodeMaster[0]);     
            }
            deferred.resolve(localArray);
            
        }   
    });

    return deferred.promise;
}
